﻿using Dapper;
using System;
using System.Linq;
using System.Data;
using EaseDapper.Abstract;
using EaseDapper.Interface;
using System.Collections.Generic;
using EaseDapper.Providers.ExpressionBuilderProvider;

namespace EaseDapper
{
    /// <summary>
    /// 基础数据管理器
    /// </summary>
    public class DataManagerClient : IDataManager
    {
        #region Properties
        private BuilderProvider BuilderContent { get; set; }
        #endregion

        public DataManagerClient(ConnectConfig config)
        {
            BuilderContent = new BuilderProvider(config);
            SqlMapper.AddTypeHandler(typeof(Dictionary<string, object>), new JsonObjectTypeHandler());
        }

        /// <summary>
        /// 添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Add<T>(T model) where T : class
        {
            try
            {
                return DapperExecute.Instance.ExecuteWithTransaction((conn, trans) =>
                {
                    return conn.Insert<T>(model, trans);
                });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="models"></param>
        /// <returns></returns>
        public int Add<T>(List<T> models) where T : class
        {
            try
            {
                return DapperExecute.Instance.ExecuteWithTransaction((conn, trans) =>
                {
                    return conn.Insert<T>(models, trans);
                });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IUpdateExpressions<T> Update<T>() where T : class
        {
            try
            {
                return BuilderContent.UpdateBuilder<T>();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Update<T>(T model) where T : class
        {
            try
            {
                return DapperExecute.Instance.ExecuteWithTransaction((conn, trans) =>
                {
                    return conn.Update<T>(model, trans);
                });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 批量修改
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Update<T>(List<T> models) where T : class
        {
            try
            {
                return DapperExecute.Instance.ExecuteWithTransaction((conn, trans) =>
                {
                    return conn.Update<T>(models, trans);
                });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IDeleteExpressions<T> Delete<T>() where T : class
        {
            try
            {
                return BuilderContent.DeleteBuilder<T>();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Delete<T>(T model) where T : class
        {
            try
            {
                return DapperExecute.Instance.ExecuteWithTransaction((conn, trans) =>
                {
                    return conn.Delete<T>(model, trans);
                });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <returns></returns>
        public int Delete<T>(object Id) where T : class
        {
            try
            {
                return DapperExecute.Instance.ExecuteWithTransaction((conn, trans) =>
                {
                    return conn.Delete<T>(Id, trans);
                });
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 根据ID获取对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id"></param>
        /// <returns></returns>
        public T Get<T>(object id) where T : class
        {
            try
            {
                T obj = default;
                DapperExecute.Instance.ExecuteWithoutTransaction((conn) =>
                {
                    obj = conn.Get<T>(id);
                });
                return obj;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 查询对象条件获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereConditions">条件信息，如where Age > @Age</param>
        /// <param name="Parameters">参数值，如new { Age = 10 }</param>
        /// <returns></returns>
        public T Get<T>(string whereConditions, object Parameters = null) where T : class
        {
            try
            {
                return GetList<T>(whereConditions, Parameters).FirstOrDefault();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }


        /// <summary>
        /// 查询对象所有数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public IEnumerable<T> GetList<T>() where T : class
        {
            try
            {
                return GetList<T>(null);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }


        /// <summary>
        /// 查询对象条件获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereConditions">条件信息，如where Age > @Age</param>
        /// <param name="Parameters">参数值，如new { Age = 10 }</param>
        /// <returns></returns>
        public IEnumerable<T> GetList<T>(string whereConditions, object Parameters = null) where T : class
        {
            try
            {
                IEnumerable<T> obj = null;
                DapperExecute.Instance.ExecuteWithoutTransaction((conn) =>
                {
                    obj = conn.GetList<T>(whereConditions, Parameters);
                });
                return obj;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 根据查询条件获取返回集合
        /// </summary>
        /// <typeparam name="T">返回对象集合</typeparam>
        /// <param name="sql">查询语句</param>
        /// <param name="Parameters">参数</param>
        /// <returns></returns>
        public IEnumerable<T> Query<T>(string sql, object Parameters = null) where T : class
        {
            try
            {
                IEnumerable<T> obj = null;
                DapperExecute.Instance.ExecuteWithoutTransaction((conn) =>
                {
                    obj = conn.Query<T>(sql, Parameters);
                });
                return obj;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 根据对象类型查询对象表的所有数据
        /// </summary>
        /// <typeparam name="T">查询对象</typeparam>
        /// <returns>返回对象集合</returns>
        public IQueryExpressions<T> Query<T>() where T : class
        {
            try
            {
                return BuilderContent.QueryBuilder<T>();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 根据查询条件获取datatable
        /// </summary>
        /// <param name="sql">查询语句</param>
        /// <param name="Parameters">参数</param>
        /// <returns></returns>
        public DataTable Query(string sql, object Parameters = null)
        {
            try
            {
                DataTable obj = new DataTable();
                DapperExecute.Instance.ExecuteWithoutTransaction((conn) =>
                {
                    obj.Load(conn.ExecuteReader(sql, Parameters as object));
                });
                return obj;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }

        /// <summary>
        /// 执行sql操作
        /// </summary>
        /// <param name="sql">sql语句</param>
        /// <param name="Parameters">参数</param>
        /// <returns></returns>
        public int Execute(string sql, object Parameters = null)
        {
            try
            {
                return DapperExecute.Instance.Execute(sql, Parameters);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.ToString());
            }
        }
    }
}
